<?php

namespace app\modules\backend\controllers;

use app\models\tableModel\AdminMenuModel;
use app\service\tool\UtilsService;
use yii\db\Exception;
use \yii\console\Exception as consoleException;
use yii\filters\VerbFilter;

/**
 * 后台菜单管理
 */
class AdminMenuController extends BaseController
{

    /**
     * {@inheritdoc}
     */
    public function behaviors()
    {
        return [
            'verbs' => [ // 请求方式
                'class' => VerbFilter::className(),
                'actions' => [
                    ### 页面
                    'index-page' => ['GET'],
                    ### 接口
                    'setting' => ['GET'],
                    'list' => ['GET'],
                    'detail' => ['GET'],
                    'create' => ['POST'],
                    'update' => ['POST'],
                    'disabled' => ['POST'],
                    'open' => ['POST'],
                    'sort' => ['POST']
                ],
            ]
        ];
    }


    /**
     * 列表页面
     * @return mixed
     */
    public function actionIndexPage()
    {

        return $this->render('index', []);
    }


    /**
     * 获取设置
     *  ` PS: 获取某些设置(如：状态列表等)以供前端使用
     * @return mixed
     */
    public function actionSetting()
    {

        // 类型 - 一般为首页[index]、表单[form]
        $type = $this->post('type');
        // 模型
        $model = AdminMenuModel::loadModel();
        return $this->jsonSuccess('成功', [
            'default_status' => $model::getStatOpen(), // 默认选中状态
            'status_list' => $model::getStatList(), // 状态文本列表值
            'sort_min' => $model::getSortMin(), // 最小排序值
            'sort_max' => $model::getSortMax(), // 最大排序值
        ]);
    }

    /**
     * 列表
     */
    public function actionList()
    {

        // 字段
        $field = ['id', 'name', 'status', 'parent_id', 'has_child', 'sort', 'font_icon', 'url'];
        // 查询内容
        $search = $this->get('search');

        $model = AdminMenuModel::loadModel();
        $paginate = $model->loadWhere($search)->getPaginate($field, [
            'loadChild' => true,
            'loadLevelIds' => true,
            'parentId' => 0
        ]);

        // 提示
        return $this->jsonSuccess('成功', [
            'total' => $paginate->getTotal(),
            'list' => $paginate->getList()
        ]);
    }

    /**
     * 创建
     */
    public function actionCreate()
    {

        // 处理下连接，去掉 '/'
        $url = trim($this->post('url'));
        $url = preg_replace('/\\\\+/', '/', $url);
        $url = preg_replace('/\/{2,}/', '/', $url);

        $data = [
            'name' => trim($this->post('name')),
            'parent_id' => $this->post('parent_id'),
            'sort' => $this->post('sort', 0),
            'status' => intval($this->post('status')),
            'url' => $url,
            'font_icon' => trim($this->post('font_icon'))
        ];

        // 如果上级编号是数组，则选择最后一个编号
        if (is_array($data['parent_id'])) {
            $data['parent_id'] = end($data['parent_id']);
        }

        try {
            // 事务
            $dbTransit = \Yii::$app->db->beginTransaction();

            // ********** 1、先添加菜单数据 **********
            $model = AdminMenuModel::loadModel();
            // 加载类数据
            $model->load($data, '');
            // 数据保存失败并返回错误信息
            if (!$model->save()) {

                // 回滚
                $dbTransit->rollBack();
                $err = $model->getFirstErrors();
                return $this->jsonFail('添加失败, 请确认各项数据是否合法', 400, [
                    'column_error' => UtilsService::getChineseErr($err)
                ]);
            }

            // ********** 2、父级菜单变为有子集 **********
            // 新父级编号
            $parentId = $model->getAttribute('parent_id');
            // 更新下旧父级 - 做判断如果新旧编号不相同做更新
            if (!$model->updateHasChildren($parentId)) {
                // 回滚
                $dbTransit->rollBack();
                return $this->jsonFail('修改失败, 请确认各项数据是否合法', 400, [
                    'error_hint' => '修改菜单存在子集失败'
                ]);
            }

            // 提交
            $dbTransit->commit();

            // 成功返回
            return $this->jsonSuccess('成功');
        } catch (Exception $error) {

            // 成功返回
            return $this->jsonFail('请求频繁，请稍后尝试', 500, [
                'error_hint' => $error->getMessage()
            ]);
        }
    }

    /**
     * 更新
     */
    public function actionUpdate()
    {

        // 编号
        $id = $this->post('id');
        if (empty($id)) {
            return $this->jsonFail('修改失败, 请确认各项数据是否合法', 400, [
                'error_hint' => '编号不能为空'
            ]);
        }

        // 处理下连接，去掉 '/'
        $url = trim($this->post('url'));
        $url = preg_replace('/\\\\+/', '/', $url);
        $url = preg_replace('/\/{2,}/', '/', $url);

        $data = [
            'name' => trim($this->post('name')),
            'parent_id' => $this->post('parent_id'),
            'sort' => $this->post('sort', 'int', 0),
            'status' => intval($this->post('status')),
            'url' => $url,
            'font_icon' => trim($this->post('font_icon'))
        ];

        // 如果上级编号是数组，则选择最后一个编号
        if (is_array($data['parent_id'])) {
            $data['parent_id'] = end($data['parent_id']);
        }


        try {
            // 事务
            $dbTransit = \Yii::$app->db->beginTransaction();

            // ********** 1、先添加菜单数据 **********
            $model = AdminMenuModel::loadModel($id);
            if (!$model) {
                // 回滚
                $dbTransit->rollBack();
                return $this->jsonFail('数据不存在', 404);
            }

            // 暂存下就数据[父级编号]
            $oldParentId = $model->getAttribute('parent_id');

            // 加载类数据
            $model->load($data, '');
            // 数据保存失败并返回错误信息
            if (!$model->save()) {

                // 回滚
                $dbTransit->rollBack();
                $err = $model->getFirstErrors();
                return $this->jsonFail('修改失败, 请确认各项数据是否合法', 400, [
                    'column_error' => UtilsService::getChineseErr($err)
                ]);
            }

            // ********** 2、父级菜单是否有子集更新 **********
            // 先更新下旧编号
            $result = $model->updateHasChildren($oldParentId);
            if (!$result) {
                // 回滚
                $dbTransit->rollBack();
                return $this->jsonFail('修改失败, 请确认各项数据是否合法', 400, [
                    'error_hint' => '修改菜单存在子集失败'
                ]);
            }

            // 新父级编号
            $newParentId = $model->getAttribute('parent_id');
            // 更新下旧父级 - 做判断如果新旧编号不相同做更新
            if ($newParentId != $oldParentId && !$model->updateHasChildren($newParentId)) {
                // 回滚
                $dbTransit->rollBack();
                return $this->jsonFail('修改失败, 请确认各项数据是否合法', 400, [
                    'error_hint' => '修改菜单存在子集失败'
                ]);
            }

            // 提交
            $dbTransit->commit();

            // 成功返回
            return $this->jsonSuccess('成功');
        } catch (Exception $error) {

            // 成功返回
            return $this->jsonFail('请求频繁，请稍后尝试', 500, [
                'error_hint' => $error->getMessage()
            ]);
        }
    }

    /**
     * 禁用条目
     * @param array $idList 数据条目|多条数组格式，如：[1,2,3]
     * @return mixed
     */
    public function actionDisabled()
    {

        $idList = $this->post('idList');

        // 看获取的编号列表是否合法
        if (empty($idList) || count($idList) <= 0) {

            return $this->jsonFail('请选择一个条目', 400, [
                'hint' => '未传输任何编号'
            ]);
        }

        // 检测多选条目
        $maxIdCount = $this->getMaxIdCount();
        if (count($idList) > intval($maxIdCount)) {
            return $this->jsonFail('每次最多选择操作' . $maxIdCount . '条数据', 400);
        }

        // 是否操作成功 - 错误一般记录到[log]日志
        $condition = ['id' => $idList];
        $data = ['status' => AdminMenuModel::getStatDisabled()];
        if (!AdminMenuModel::updateField($condition, $data)) {

            $error = UtilsService::getModelError(AdminMenuModel::getStaticErrors());
            // 将返回数据库级错误，暂不返回 会在日志中记录
            return $this->jsonFail($error['msg'], $error['column'] == 'unknown' ? 500 : 400);
        }

        return $this->jsonSuccess('成功');
    }

    /**
     * 开启条目
     * @param array $idList 数据条目|多条数组格式，如：[1,2,3]
     * @return mixed
     */
    public function actionOpen()
    {

        $idList = $this->post('idList');

        // 看获取的编号列表是否合法
        if (empty($idList) || count($idList) <= 0) {

            return $this->jsonFail('请选择一个条目', 400, [
                'hint' => '未传输任何编号'
            ]);
        }

        // 检测多选条目
        $maxIdCount = $this->getMaxIdCount();
        if (count($idList) > intval($maxIdCount)) {
            return $this->jsonFail('每次最多选择操作' . $maxIdCount . '条数据', 400);
        }

        // 是否操作成功 - 错误一般记录到[log]日志
        $condition = ['id' => $idList];
        $data = ['status' => AdminMenuModel::getStatOpen()];
        if (!AdminMenuModel::updateField($condition, $data)) {

            $error = UtilsService::getModelError(AdminMenuModel::getStaticErrors());
            // 将返回数据库级错误，暂不返回 会在日志中记录
            return $this->jsonFail($error['msg'], $error['column'] == 'unknown' ? 500 : 400);
        }

        return $this->jsonSuccess('成功');
    }

    /**
     * 详情
     * @param string $id 编号
     * @return mixed
     */
    public function actionDetail()
    {

        // 获取全部POST数据
        $id = $this->get('id');

        // 验证 规格编号
        if (empty($id)) {

            return $this->jsonFail('数据不存在', 404, [
                'hint' => '请传输编号'
            ]);
        }

        $model = AdminMenuModel::loadModel($id);

        if ($model == null) {

            return $this->jsonFail('数据不存在', 404, [
                'hint' => '数据不存在，请核对'
            ]);
        }

        // 仅仅返回指定 字段
        $detail = $model->getAttributes([
            'id',
            'name',
            'status',
            'sort',
            'url',
            'font_icon',
            'parent_id'
        ]);

        // $detail['parent_id'] = $model->lastGetLvIdList($detail['parent_id']);

        return $this->jsonSuccess('成功', AdminMenuModel::loadModel()->formatData($detail));
    }

    /**
     * 排序
     * @param array $idList 数据条目|多条数组格式，如：[1,2,3]
     * @return mixed
     */
    public function actionSort()
    {

        $idList = $this->post('sortData');

        // 看获取的[data]是否为空
        if (empty($idList) || count($idList) <= 0) {

            return $this->jsonFail('排序数据不能为空', 400);
        }

        // 检测多选条目
        $maxIdCount = $this->getMaxIdCount();
        if (count($idList) > intval($maxIdCount)) {
            return $this->jsonFail('每次最多选择操作' . $maxIdCount . '条数据', 400);
        }

        foreach ($idList as $k => $v) {

            $v = intval(trim($v));

            // 看获取的[data]是否为空
            if (!isset($v)) return $this->jsonFail('排序不能为空', 400);

            // 排序操作
            if (!AdminMenuModel::updateField(['id' => $k], ['sort' => $v])) {

                $error = UtilsService::getModelError(AdminMenuModel::getStaticErrors());
                // 将返回数据库级错误，暂不返回 会在日志中记录
                return $this->jsonFail($error['msg'], $error['column'] == 'unknown' ? 500 : 400);
            }
        }

        return $this->jsonSuccess('成功');
    }
}
